package me.helllp.dake.generator.meta.third;

import com.squareup.javapoet.AnnotationSpec;
import freemarker.template.TemplateException;
import lombok.Getter;
import lombok.Setter;
import me.helllp.dake.common.anno.MataGenerator;
import me.helllp.dake.generator.FreeMarkerUtil;
import me.helllp.dake.generator.config.GeneratorEngineConfiguration;
import me.helllp.dake.generator.config.services.RdbmsConfiguration;
import me.helllp.dake.generator.engine.AbstractGenerator;
import me.helllp.dake.generator.engine.RdbmsGenerator;
import me.helllp.dake.generator.config.enums.DbTypeEnum;
import me.helllp.dake.generator.meta.*;
import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.beanutils.BeanUtils;
import org.mybatis.spring.annotation.MapperScan;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;


public class RdbmsMetaData extends AbstractMetaData implements IThirdComponent {
    @Getter
    @Setter
    private RdbmsConfiguration rdbmsConfiguration;

    @Getter
    @Setter
    private DbTypeEnum dbType;

    @Getter
    @Setter
    private String hostName;

    @Getter
    @Setter
    private String port;

    @Getter
    @Setter
    private String userId;

    @Getter
    @Setter
    private String password;

    /**
     * 数据库的名称
     */
    @Getter
    @Setter
    private String catalog;

    @Getter
    @Setter
    private String schema;

    @MataGenerator
    @Getter
    private String driverClass;

    @MataGenerator
    @Getter
    private String connectionURL;

    /**
     * 其他配置信息
     */
    @MataGenerator
    @Getter
    private Properties properties;

    public RdbmsMetaData(RdbmsConfiguration rdbmsConfiguration) throws InvocationTargetException, IllegalAccessException, TemplateException, IOException {
        this.rdbmsConfiguration = rdbmsConfiguration;

        BeanUtils.copyProperties(this, this.rdbmsConfiguration);
        // 构造其他信息
        BeanMap beanMap = new BeanMap(this);
        this.connectionURL = FreeMarkerUtil.genSrc(this.getDbType().makeUrlTemplate(), (Map)beanMap);
        this.driverClass = this.getDbType().makeDriverName();
    }

    @Override
    public Map<String, Object> toSpringBootSettings() {
        Map<String, Object> map = new HashMap<>();

        map.put(ProjectPropertyRegistry.SPRING_DATASOURCE_DRIVER, this.driverClass);
        map.put(ProjectPropertyRegistry.SPRING_DATASOURCE_URL, this.connectionURL);
        map.put(ProjectPropertyRegistry.SPRING_DATASOURCE_USERNAME, this.userId);
        map.put(ProjectPropertyRegistry.SPRING_DATASOURCE_PASSWORD, this.password);

        return map;
    }

    @Override
    public List<PomMetaData> toDependency() {
        List<PomMetaData> list = new ArrayList<>();
        list.addAll(dbType.makeDependency());
        list.add(new PomMetaData("com.baomidou", "mybatis-plus-boot-starter", null));
        return list;
    }

    @Override
    public AbstractGenerator toGenerator(GeneratorEngineConfiguration engineConfiguration, ProjectMetaData projectMetaData) throws TemplateException, IOException, InvocationTargetException, IllegalAccessException {
        RdbmsGenerator generator = new RdbmsGenerator(projectMetaData);
        generator.initGenerator(engineConfiguration);
        return generator;
    }

    @Override
    public List<AnnotationSpec> toAnnotations(ProjectMetaData projectMetaData) {
        return Arrays.asList(
                AnnotationSpec.builder(MapperScan.class).addMember("value", "$S", projectMetaData.getBasePackage() + ".mapper").build());
    }

    @Override
    public void initMetaData() throws IOException {

    }
}
